package com.atstudent.gmall.product.biz.impl;

import com.alibaba.fastjson.JSON;
import com.atstudent.gmall.common.constant.GmallConstant;
import com.atstudent.gmall.product.biz.SkuBizService;
import com.atstudent.gmall.product.entity.SkuInfo;
import com.atstudent.gmall.product.entity.SpuSaleAttr;
import com.atstudent.gmall.product.mapper.BaseCategory1Mapper;
import com.atstudent.gmall.product.mapper.SkuInfoMapper;
import com.atstudent.gmall.product.mapper.SkuSaleAttrValueMapper;
import com.atstudent.gmall.product.mapper.SpuSaleAttrMapper;
import com.atstudent.gmall.product.vo.AttrValueConcatVo;
import com.atstudent.gmall.product.vo.CategoryView;
import com.atstudent.gmall.product.vo.SkuDetailVo;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RBloomFilter;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.stream.Collectors;

/**
 * @Author 薛有朋
 * @CreatDate 2024/12/1 21:04
 **/
@Service
@Slf4j
public class SkuBizServiceImpl implements SkuBizService {

    @Autowired
    private BaseCategory1Mapper baseCategory1Mapper;

    @Autowired
    private SkuInfoMapper skuInfoMapper;

    @Autowired
    private SpuSaleAttrMapper spuSaleAttrMapper ;

    @Autowired
    private SkuSaleAttrValueMapper skuSaleAttrValueMapper ;

    //注入Redisson客户端
    @Autowired
    private RedissonClient redissonClient;

    @Autowired
    private ThreadPoolExecutor threadPoolExecutor;


    @Override
    public CategoryView findCategoryViewBySkuId(Long skuId) {
        CategoryView categoryView = baseCategory1Mapper.findCategoryViewBySkuId(skuId);
        return categoryView;
    }

    @Override
    public SkuInfo findSkuInfoAndImageBySkuId(Long skuId) {
        return skuInfoMapper.findSkuInfoAndImageBySkuId(skuId);
    }

    @Override
    public SkuInfo findSkuInfoBySkuId(Long skuId) {
        return skuInfoMapper.selectById(skuId);
    }

    @Override
    public List<SpuSaleAttr> findSpuSalAttrBySkuId(Long skuId) {
        return spuSaleAttrMapper.findSpuSalAttrBySkuId(skuId);
    }

    @Override
    public List<AttrValueConcatVo> findSkuAttrValueConcatBySkuId(Long skuId) {
        return skuSaleAttrValueMapper.findSkuAttrValueConcatBySkuId(skuId);
    }

    @Override
    public SkuDetailVo findSkuDetailVo(Long skuId) {
        SkuDetailVo skuDetailVo = new SkuDetailVo() ;
        SkuInfo skuInfoAndImg = findSkuInfoAndImageBySkuId(skuId);
        if (skuInfoAndImg == null){
            return  null;
        }
        skuDetailVo.setSkuInfo(skuInfoAndImg);

        CompletableFuture<Void> cf1 = CompletableFuture.runAsync(() -> {
            CategoryView categoryView = findCategoryViewBySkuId(skuId);
            skuDetailVo.setCategoryView(categoryView);
        }, threadPoolExecutor);

        CompletableFuture<Void> cf2 = CompletableFuture.runAsync(() -> {
            BigDecimal price = findSkuInfoBySkuId(skuId).getPrice();
            skuDetailVo.setPrice(price);
        }, threadPoolExecutor);


        CompletableFuture<Void> cf3 = CompletableFuture.runAsync(() -> {
            List<SpuSaleAttr> spuSaleAttrList = findSpuSalAttrBySkuId(skuId);
            skuDetailVo.setSpuSaleAttrList(spuSaleAttrList);
        }, threadPoolExecutor);

        CompletableFuture<Void> cf4 = CompletableFuture.runAsync(() -> {
            List<AttrValueConcatVo> concatVoList = findSkuAttrValueConcatBySkuId(skuId);
            Map<String, Long> map = concatVoList
                    .stream()
                    .collect(Collectors.toMap(attrValueConcatVo -> attrValueConcatVo.getAttrValueConcat(), attrValueConcatVo -> attrValueConcatVo.getSkuId()));
            //把map数据转换成json格式
            String toJSONString = JSON.toJSONString(map);
            skuDetailVo.setValuesSkuJson(toJSONString);
        }, threadPoolExecutor);

        CompletableFuture.allOf(cf1 , cf2 , cf3 , cf4).join();
        return skuDetailVo;
    }

    @Override
    public List<Long> findAllSkuIds() {
        //无条件查询所有的skuInfo数据
        List<SkuInfo> skuInfoList = skuInfoMapper.selectList(null);
        //拿到skuId
        List<Long> skuIdList = skuInfoList.stream().map(skuInfo -> skuInfo.getId()).collect(Collectors.toList());
        return skuIdList;
    }

    //使用Redisson框架的分布式布隆过滤器
    @PostConstruct
    public void initBloomFilter(){
        RBloomFilter<Long> rBloomFilter = redissonClient.getBloomFilter(GmallConstant.REDIS_SKUID_BLOOM_FILTER);
        rBloomFilter.tryInit(1000000,0.000001);
        //调用查询所有skuid的方法
        List<Long> allSkuIds = findAllSkuIds();
        allSkuIds.stream().forEach(skuId -> {
            rBloomFilter.add(skuId);
        });
        log.info("分布式布隆过滤器初始化成功了。。。");
    }
}

